package com.example.clock_demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.clock_demo.common.Result;
import com.example.clock_demo.dto.UserDTO;
import com.example.clock_demo.entity.SysUser;
import com.example.clock_demo.mapper.SysUserMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/users")
@Api(tags = "用户管理")
public class UserController {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @PostMapping
    @ApiOperation("创建用户")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<String> createUser(@Valid @RequestBody UserDTO userDTO) {
        // 检查用户名是否已存在
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername, userDTO.getUsername());
        if (sysUserMapper.selectOne(wrapper) != null) {
            return Result.error("用户名已存在");
        }

        // 检查员工编号是否已存在
        if (StringUtils.hasText(userDTO.getEmployeeNo())) {
            LambdaQueryWrapper<SysUser> empNoWrapper = new LambdaQueryWrapper<>();
            empNoWrapper.eq(SysUser::getEmployeeNo, userDTO.getEmployeeNo());
            if (sysUserMapper.selectOne(empNoWrapper) != null) {
                return Result.error("员工编号已存在");
            }
        }

        SysUser user = new SysUser();
        BeanUtils.copyProperties(userDTO, user);
        user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        if (user.getRole() == null) {
            user.setRole("EMPLOYEE");
        }
        if (user.getStatus() == null) {
            user.setStatus(1);
        }

        sysUserMapper.insert(user);
        return Result.success("用户创建成功");
    }

    @PutMapping("/{id}")
    @ApiOperation("更新用户")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<String> updateUser(@PathVariable Long id, @Valid @RequestBody UserDTO userDTO) {
        SysUser user = sysUserMapper.selectById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 检查用户名是否被其他用户使用
        if (!user.getUsername().equals(userDTO.getUsername())) {
            LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUser::getUsername, userDTO.getUsername());
            if (sysUserMapper.selectOne(wrapper) != null) {
                return Result.error("用户名已被使用");
            }
        }

        // 检查员工编号是否被其他用户使用
        if (StringUtils.hasText(userDTO.getEmployeeNo()) && !userDTO.getEmployeeNo().equals(user.getEmployeeNo())) {
            LambdaQueryWrapper<SysUser> empNoWrapper = new LambdaQueryWrapper<>();
            empNoWrapper.eq(SysUser::getEmployeeNo, userDTO.getEmployeeNo());
            if (sysUserMapper.selectOne(empNoWrapper) != null) {
                return Result.error("员工编号已被使用");
            }
        }

        BeanUtils.copyProperties(userDTO, user, "id", "password");
        if (StringUtils.hasText(userDTO.getPassword())) {
            user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        }

        sysUserMapper.updateById(user);
        return Result.success("用户更新成功");
    }

    @DeleteMapping("/{id}")
    @ApiOperation("删除用户")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<String> deleteUser(@PathVariable Long id) {
        sysUserMapper.deleteById(id);
        return Result.success("用户删除成功");
    }

    @GetMapping("/{id}")
    @ApiOperation("获取用户详情")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<UserDTO> getUser(@PathVariable Long id) {
        SysUser user = sysUserMapper.selectById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }

        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO, "password");
        return Result.success(userDTO);
    }

    @GetMapping("/page")
    @ApiOperation("分页查询用户")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<Page<UserDTO>> getUserPage(
            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
            @ApiParam("每页大小") @RequestParam(defaultValue = "10") Integer pageSize,
            @ApiParam("用户名") @RequestParam(required = false) String username,
            @ApiParam("真实姓名") @RequestParam(required = false) String realName,
            @ApiParam("部门") @RequestParam(required = false) String department,
            @ApiParam("角色") @RequestParam(required = false) String role) {

        Page<SysUser> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(username)) {
            wrapper.like(SysUser::getUsername, username);
        }
        if (StringUtils.hasText(realName)) {
            wrapper.like(SysUser::getRealName, realName);
        }
        if (StringUtils.hasText(department)) {
            wrapper.like(SysUser::getDepartment, department);
        }
        if (StringUtils.hasText(role)) {
            wrapper.eq(SysUser::getRole, role);
        }
        
        wrapper.orderByDesc(SysUser::getCreateTime);
        
        Page<SysUser> userPage = sysUserMapper.selectPage(page, wrapper);
        
        Page<UserDTO> dtoPage = new Page<>();
        BeanUtils.copyProperties(userPage, dtoPage, "records");
        
        List<UserDTO> dtoList = userPage.getRecords().stream().map(user -> {
            UserDTO dto = new UserDTO();
            BeanUtils.copyProperties(user, dto, "password");
            return dto;
        }).collect(Collectors.toList());
        
        dtoPage.setRecords(dtoList);
        
        return Result.success(dtoPage);
    }
}